package com.joymart.user.rest;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.joymart.common.error.handling.JoymartBusinessException;
import com.joymart.common.utils.SecurityUtils;
import com.joymart.prepaid.wallet.service.PrepaidWalletService;
import com.joymart.user.model.BusinessRole;
import com.joymart.user.model.CachedUser;
import com.joymart.user.model.User;
import com.joymart.user.repo.UserRepository;
import com.joymart.user.service.UserCacheManager;
import com.joymart.user.service.UserService;
import lombok.Data;
import org.json.JSONObject;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import static com.joymart.common.utils.ValidationUtils.*;


@RestController
public class UserController {

    @Autowired
    private UserService userService;
    @Autowired
    private UserCacheManager userCacheManager;
    @Autowired
    private PrepaidWalletService prepaidWalletService;
    @Autowired
    private ObjectMapper objectMapper;
    @Autowired
    private UserRepository userRepository;

    @GetMapping("/me")
    public Object currentUserInfo() {
        String userId = SecurityUtils.getCurrentUserId();
        CachedUser cachedUser = userCacheManager.get(userId);
        if (cachedUser.getUser().isPartyA()) {
            return cachedUser;
        } else {
            Map map = objectMapper.convertValue(cachedUser, Map.class);
            User shop = cachedUser.getBusinessRoles().contains(BusinessRole.AG_SHOP) ?
                    cachedUser.getUser() :
                    Optional.ofNullable(userCacheManager.upwardSearchUntil(cachedUser,
                                    cu -> cu.getBusinessRoles().contains(BusinessRole.AG_SHOP)))
                            .map(CachedUser::getUser).orElse(null);
            map.put("shop", shop);
            return map;
        }
    }

    /**
     * 当前用户邀请的用户
     * @return
     */
    @GetMapping("/invitees")
    public Object currentUserInvitees() {
        String userId = SecurityUtils.getCurrentUserId();
        CachedUser cachedUser = userCacheManager.get(userId);

        if (cachedUser.getUser().isPartyA()) {
           return Collections.emptyList();
        } else {
            List<CachedUser> invitees= cachedUser.getDownstreamIds().stream()
                    .map(userCacheManager::get)
                    .toList();
            return invitees;
        }
    }

    /**
     * 登录
     *
     * @param username
     * @param rawPassword
     * @return
     */
    @PostMapping("/login")
    public Map<String, Object> login(@RequestParam String username, @RequestParam("password") String rawPassword) {
        return userService.generateJwt(username, rawPassword);
    }


    /**
     * 修改密码
     */
    @PutMapping("/password/mine")
    public void changePassword(@RequestBody  Map<String, String> params) {
        String userId = SecurityUtils.getCurrentUserId();
        String oldPassword = params.get("oldPassword");
        String newPassword = params.get("newPassword");
        validatePassword(newPassword);
        userService.changePassword( userId, oldPassword, newPassword);
    }

    /**
     * 修改头像
     */
    @PutMapping("/avatar/mine")
    public void changeAvatar(@RequestBody  Map<String, String> params) {
        String userId = SecurityUtils.getCurrentUserId();
        String avatar = params.get("avatar");
        validateImageUrl(avatar);
        userService.changeAvatar(userId, avatar);
    }

    /**
     * 修改收款快捷文本
     */
    @PutMapping("/paymentText/mine")
    public void changePaymentText(@RequestBody  Map<String, String> params) {
        String userId = SecurityUtils.getCurrentUserId();
        String paymentText = params.get("paymentText");
        userService.changePaymentText(userId, paymentText);
    }

    /**
     * 修改联系人二维码
     */
    @PutMapping("/qrCode/mine")
    public void changeQrCode(@RequestBody  Map<String, String> params) {
        String userId = SecurityUtils.getCurrentUserId();
        String qrCode = params.get("qrCodeImage");
        validateImageUrl(qrCode);
        userService.changeQrCode(userId, qrCode);
    }

    /**
     * 注册
     *
     * @return
     */
    @PostMapping("/signup")
    public void signup(@RequestBody SignupParam signupParam) {
        signupParam.validate();
        userService.createNonPartyAUser(signupParam.toUser(), signupParam.getPassword(), signupParam.getInvitedByCode());
    }


    @GetMapping("/prepaidWallet/balance")
    public Map<String, BigDecimal> getPrepaidWalletBalance() {
        CachedUser user = userCacheManager.get(SecurityUtils.getCurrentUserId());
        if(!user.getBusinessRoles().contains(BusinessRole.AG_SHOP)) {
            throw new JoymartBusinessException("预付货款功能仅对店铺开放");
        }
        BigDecimal balance = prepaidWalletService.findByUserId(user.getId()).getBalance();
        return Map.of("balance",balance);
    }

    @Data
    public static class SignupParam {
        private String password;
        private String nickname;
        private String mobile;
        private String invitedByCode;

        private void validate() {
            validateNickname(nickname);
            validatePassword(password);
            validatePhone(mobile);
            validateInvitedBy(invitedByCode);
        }

        public User toUser() {
            User user = new User();
            BeanUtils.copyProperties(this, user);
            user.setUsername(this.getMobile());
            user.setMeta(new JSONObject());
            return user;
        }
    }

}
